import java.awt.Rectangle;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Random;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSItemTile;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;

public class ScapeRuneIsland extends Random {
	private final int COOK_GIVE = 30;
	private int currentStatue;
	private final int EVIL_BOB = 2479;
	private final int FISH = 20;
	private final int FISH_ID = 6202;
	private final int FISHING_NET = 6209;
	private final int FISHING_SPOT = 8986;
	private final int GET_STATUE = 10;
	private final int PORTAL = 8987;
	private final int SERVANT = 2481;
	private int state;
	private final int STATUE_EAST = 8991;
	private final int STATUE_NORTH = 8992;
	private final int STATUE_SOUTH = 8990;
	private final int STATUE_WEST = 8993;
	private final int UNCOOKED_FISH_ID = 6200;
	private final int UNCOOKING_POT = 8985;

	@Override
	public boolean activateCondition() {
		state = 10;
		return findObject(UNCOOKING_POT) != null;
	}

	private RSItemTile closestFishNet() {
		for (int i = 0; i < 20; i++) {
			if (getGroundItemByID(i, FISHING_NET) != null) {
				return getGroundItemByID(i, FISHING_NET);
			}
		}
		return null;
	}

	public RSObject findObjectIn(final Rectangle area, final int id) {
		RSObject cur = null;
		int dist = -1;
		for (int x = 0; x < 104; x++) {
			for (int y = 0; y < 104; y++) {
				final RSObject o = getObjectAt(x + Bot.getClient().getBaseX(),
						y + Bot.getClient().getBaseY());
				if (o != null) {
					boolean isObject = false;
					if (o.getID() == id
							&& area.contains(o.getLocation().getX(), o
									.getLocation().getY())) {
						isObject = true;
					}
					if (isObject) {
						final int distTmp = getRealDistanceTo(o.getLocation(),
								true);
						if (distTmp != -1) {
							if (cur == null) {
								dist = distTmp;
								cur = o;
							} else if (distTmp < dist) {
								cur = o;
								dist = distTmp;
							}
						}
					}
				}
			}
		}
		return cur;
	}

	@Override
	public String getAuthor() {
		return "Alowaniak";
	}

	@Override
	public String getName() {
		return "ScapeRune Island";
	}

	@Override
	public double getVersion() {
		return 1;
	}

	@Override
	public int loop() {
		switch (state) {
		case GET_STATUE:
			if (getInventoryCount() > 26) {
				log
						.info("Your character had more than 26 items in it's inven.");
				log
						.info("This means that it should have to drop items to be able to fish");
				log
						.info("However, if you do you get an annoying window before you leave");
				log.info("and I haven't made a fix for that.");
				log.info("So shutting down all scripts now.");
				stopAllScripts();
				return -1;
			}
			final RSNPC servant = getNearestNPCByID(SERVANT);
			if (getMyPlayer().isMoving() || getMyPlayer().getAnimation() != -1) {
				log.info("walking");
				return random(300, 600);
			}
			if (currentStatue < 1) {
				if (RSInterface.getInterface(186).isValid()) {
					if (pointOnScreen(Calculations.tileToScreen(findObject(
							STATUE_SOUTH).getLocation()))) {
						currentStatue = STATUE_SOUTH;
					} else if (pointOnScreen(Calculations
							.tileToScreen(findObject(STATUE_EAST).getLocation()))) {
						currentStatue = STATUE_EAST;
					} else if (pointOnScreen(Calculations
							.tileToScreen(findObject(STATUE_NORTH)
									.getLocation()))) {
						currentStatue = STATUE_NORTH;
					} else if (pointOnScreen(Calculations
							.tileToScreen(findObject(STATUE_WEST).getLocation()))) {
						currentStatue = STATUE_WEST;
					}
					return random(500, 1000);
				}
				if (canContinue()) {
					clickContinue();
					return random(500, 1000);
				}
				atNPC(servant, "Talk");
				return random(300, 600);
			} else {
				walkTileMM(findObject(currentStatue).getLocation());
				state = FISH;
				return random(500, 1000);
			}

		case FISH:
			if (getMyPlayer().isMoving() || getMyPlayer().getAnimation() != -1) {
				return random(300, 600);
			}
			if (inventoryContains(FISH_ID)) {
				walkTileMM(findObject(UNCOOKING_POT).getLocation());
				state = COOK_GIVE;
				return random(500, 1000);
			}
			if (inventoryContains(FISHING_NET)) {
				final Rectangle locAroundStatue = new Rectangle(findObject(
						currentStatue).getLocation().getX() - 4, findObject(
						currentStatue).getLocation().getY() - 4, findObject(
						currentStatue).getLocation().getX() + 4, findObject(
						currentStatue).getLocation().getY() + 4);
				atObject(findObjectIn(locAroundStatue, FISHING_SPOT), "Net");
				return random(500, 1000);
			}
			final RSItemTile net = closestFishNet();
			if (net != null) {
				if (!tileOnScreen(net)) {
					walkTileMM(net);
					return random(500, 1000);
				} else {
				}
			} else {
				return random(500, 1000);
			}
			atTile(closestFishNet(), "Take");
			return random(500, 1000);

		case COOK_GIVE:
			if (getMyPlayer().isMoving() || getMyPlayer().getAnimation() != -1) {
				return random(300, 600);
			}
			if (getContinueInterface() != null) {
				while (canContinue()) {
					clickContinue();
					wait(random(1000, 1200));
				}
				if (atObject(findObject(PORTAL), "Enter")) {
					return -1;
				}
				return random(500, 1000);
			}
			if (inventoryContains(UNCOOKED_FISH_ID)) {
				atInventoryItem(UNCOOKED_FISH_ID, "Use");
				atNPC(getNearestNPCByID(EVIL_BOB), "Use");
				return random(500, 1000);
			}
			useItem(getInventoryItemByID(FISH_ID), findObject(UNCOOKING_POT));
			return random(500, 1000);
		}
		return -1;
	}
}
